#include <jni.h>
#include <string>
#include "include/core/SkPaint.h"
#include <include/core/SkBitmap.h>
#include <include/core/SkFont.h>
#include "include/core/SkCanvas.h"
#include "include/core/SkFontMgr.h"
#include "gpu/gl/GrGLTypes.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkColor.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkTextBlob.h"
#include "include/effects/SkGradientShader.h"
#include "CustomSkiaDraw.h"
#include "skia/include/core/SkImageInfo.h"
#include "skia/include/core/SkAlphaType.h"

#include <android/bitmap.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>

#include <android/log.h>
#include <include/private/SkColorData.h>
#include <include/core/SkSurface.h>

#include "JSAppBinding.h"

#include <unistd.h>


#define TAG "JNI_TAG"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)


extern "C"
JNIEXPORT void JNICALL
render(JNIEnv *env,
       jclass thiz,
       jobject jSurface,
       jint width,
       jint height) {

}

static const char *const className = "com/compose/skia/CanvasLoader";
static const JNINativeMethod gMethods[] = {
    {"render", "(Landroid/view/Surface;II)V", (void *) render}
};


static int pfd[2];
static pthread_t thr;
static const char *tag = "stdout";

static void *thread_func(void *) {
  ssize_t rdsz;
  char buf[128];
  while ((rdsz = read(pfd[0], buf, sizeof buf - 1)) > 0) {
    if (buf[rdsz - 1] == '\n') --rdsz;
    buf[rdsz] = 0;  /* add null-terminator */
    __android_log_write(ANDROID_LOG_INFO, tag, buf);
  }
  return 0;
}

int start_logger() {
  /* make stdout line-buffered and stderr unbuffered */
  setvbuf(stdout, 0, _IOLBF, 0);
  setvbuf(stderr, 0, _IONBF, 0);

  /* create the pipe and redirect stdout and stderr */
  pipe(pfd);
  dup2(pfd[1], STDOUT_FILENO);
  dup2(pfd[1], STDERR_FILENO);

  /* spawn the logging thread */
  if (pthread_create(&thr, 0, thread_func, 0) == -1) {
    return -1;
  }
  pthread_detach(thr);
  return 0;
}


JavaVM *g_vm;
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
  JNIEnv *env = NULL;
  jint result;
  g_vm = vm;
  start_logger();
  if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
    return -1;
  }

  jclass clazz = env->FindClass(className);
  if (!clazz) {
    LOGE("can not find class");
    return -1;
  }

  if (env->RegisterNatives(clazz,
                           gMethods,
                           sizeof(gMethods) / sizeof(gMethods[0])) < 0) {
    LOGE("can not register method");
    return -1;
  }

  // 注册JSApp
  if (int ret = bindingJSApp(env) < 0) {
    LOGE("can not register JSApp ");
    return ret;
  }

  return JNI_VERSION_1_6;
}
